package com.chuangke.lowcode.service;

import cn.hutool.core.util.StrUtil;
import com.chuangke.admin.service.SysDictService;
import com.chuangke.common.exception.ChuangkeException;
import com.chuangke.common.utils.SpringContextUtil;
import com.chuangke.lowcode.EntityModelConstants;
import com.chuangke.lowcode.LowCodeContext;
import com.chuangke.lowcode.LowCodeExecutor;
import com.chuangke.metadata.constant.MetaDataConstant;
import com.chuangke.metadata.entity.SysBisModel;
import com.chuangke.metadata.entity.SysDataComponent;
import com.chuangke.metadata.service.SysBisModelService;
import com.chuangke.metadata.service.SysDataComponentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 帮助字典加载服务
 */
@Service
public class SysDictLoadService {


    @Autowired
    private SysDataComponentService sysDataComponentService;

    @Autowired
    private SysDictService sysDictService;
    @Autowired
    private SysBisModelService sysBisModelService;

    @Autowired
    private LowCodeExecutor lowCodeExecutor;

    /**
     * 加载数据
     * @param dataServiceCode 数据服务code(sys_data_component.code)
     * @return
     */
    public Map<String,Object> loadData(String dataServiceCode) {
        List<SysDataComponent> dataComponents = sysDataComponentService.findList() ;
        Map<String,SysDataComponent> map = dataComponents.stream().collect(Collectors.toMap(SysDataComponent::getCode, a -> a));
        SysDataComponent dataComponent = map.get(dataServiceCode) ;
        if(dataComponent == null) {
            return new HashMap<>() ;
        }

        List dictDatas = loadData(dataComponent) ;

        SysBisModel bisModel = sysBisModelService.loadBisModel(dataComponent.getBisModelId()) ;

        Map<String,Object> resultMap = new HashMap<>() ;
        resultMap.put("datas", dictDatas) ;
        resultMap.put("bisModel", bisModel) ;
        return resultMap;
    }

    public List loadData(SysDataComponent dataComponent) {
        List dictDatas = null ;
        switch(dataComponent.getType()){
            case MetaDataConstant.DICT_SERVICE_COMMON:
                if(StrUtil.isEmpty(dataComponent.getDictType())){
                    throw new ChuangkeException("字典类型不能为空") ;
                }
                dictDatas = sysDictService.findTree(dataComponent.getDictType()) ;
                break;
            case MetaDataConstant.DICT_SERVICE_LOWCODE:
                if(StrUtil.isEmpty(dataComponent.getEntityName())){
                    throw new ChuangkeException("实体标识不能为空") ;
                }
                LowCodeContext context = new LowCodeContext()
                        .setEntityModel(EntityModelConstants.getEntityModel(dataComponent.getEntityName()));
                lowCodeExecutor.query(context) ;
                dictDatas = (List) context.getResult();
                break;
            case MetaDataConstant.DICT_SERVICE_CUSTOM:
                if(StrUtil.isEmpty(dataComponent.getDictServiceMethod())){
                    throw new ChuangkeException("服务加载配置不能为空") ;
                }

                String[] splits = dataComponent.getDictServiceMethod().split("\\.") ;

                if(splits.length != 2){
                    throw new ChuangkeException("服务加载配置格式不正确") ;
                }

                Object service = SpringContextUtil.getBean(splits[0]) ;

                try {
                    Method method = service.getClass().getMethod(splits[1]) ;
                    dictDatas = (List)method.invoke(service);
                } catch (Exception e) {
                    throw new ChuangkeException(e);
                }
                break;
            default:
                throw new ChuangkeException("未识别的数据服务类型") ;
        }
        return dictDatas ;
    }
}
